home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / HyperCuber Source / HyperCuber 2.0 Source.sit / HyperCuber 2.0 Source / CHyperCuberDoc.cp < prev    next >
Text File  |  1994-05-05  |  25KB  |  831 lines

  1. /****
  2.  * CHyperCuberDoc.c
  3.  *
  4.  *    Document methods for a typical application.
  5.  *
  6.  *  Copyright ⌐ 1990 Symantec Corporation.  All rights reserved.
  7.  *
  8.  ****/
  9.  
  10. #include "CControlsDirector.h"
  11. #include "CEnhancedWindow.h"
  12. #include "CHyperCuberDoc.h"
  13. #include "CHyperCuberPane.h"
  14. #include "CHyperCuberPrefs.h"
  15. #include "CGraphic.h"
  16.  
  17. #include <CSizeBox.h>
  18.  
  19. #include "HyperCuber Balloons.h"
  20. #include "HyperCuber Commands.h"
  21.  
  22. #include <string.h>
  23. #include <stdio.h>
  24. #include <fstream.h>
  25. #include <strstrea.h>
  26.  
  27. #define    WINDHyperCuber        500        /* Resource ID for WIND template */
  28.  
  29. //===================================== Globals =====================================\\
  30.  
  31. extern CApplication         *gApplication;    /* The application */
  32. extern CBartender            *gBartender;    /* The menu handling object */
  33. extern CClipboard            *gClipboard;    /* The clipboard */
  34. extern CDesktop                *gDesktop;        /* The enclosure for all windows */
  35. extern CBureaucrat            *gGopher;        /* The current boss in the chain of command */
  36. extern OSType                gSignature;        /* The application's signature */
  37. extern CError                *gError;        /* The global error handler */
  38.  
  39. extern CHyperCuberPrefs        *gPrefs;        //  The preferences
  40.  
  41. extern Boolean                menubar_hidden;    //  TRUE if the menubar is currently hidden
  42. extern short                menubar_height;    //  The height of the menubar (if any)
  43.  
  44. extern Boolean                drawing_disabled;//  TRUE if drawing is disabled
  45.  
  46.  
  47. //=============================== Procedure Prototypes ===============================\\
  48.  
  49. extern void verify_window_rect (Rect *bounds);
  50. extern "C" void show_menubar(void);
  51. extern "C" void hide_menubar(void);
  52. extern void CreateNCube(long n, char *filename);
  53. extern void adjust_offscreen_pixmap(CGrafPort *color_port, Rect *bounds);
  54. void HideControlDirector(CObject *director);
  55. void ShowControlDirector(CObject *director);
  56.  
  57.  
  58. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  59. //| CHyperCuberDoc::IHyperCuberDoc
  60. //| 
  61. //| Purpose: Initialize a HyperCuberdocument.
  62. //|
  63. //| Parameters: superclass parameters
  64. //|_________________________________________________________
  65.  
  66. void CHyperCuberDoc::IHyperCuberDoc(CApplication *aSupervisor, Boolean printable)
  67. {
  68.  
  69.     CDocument::IDocument(aSupervisor, printable);    //  Initialize this as a Document
  70.  
  71.     graphic = (CGraphic *) new(CGraphic);            //  Create a Graphic
  72.     ((CGraphic*) graphic)->IGraphic();                //  Initialize the Graphic
  73.                                 
  74.     controls_directors = new(CList);                //  Set up the controls list
  75.     controls_directors->IList();
  76.     
  77.     BecomeGopher(TRUE);
  78.     
  79. }    //==== CHyperCuberDoc::IHyperCuberDoc() ====\\
  80.  
  81.  
  82.  
  83. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  84. //| CHyperCuberDoc::Dispose
  85. //|
  86. //| Purpose: Dispose of a HyperCuberdocument
  87. //|
  88. //| Parameters: none
  89. //|_________________________________________________________
  90.  
  91. void CHyperCuberDoc::Dispose()
  92.  
  93. {
  94.  
  95.     ((CEnhancedWindow *) itsWindow)->
  96.         GetRect(&gPrefs->prefs.graphics_window_position);//  Save the graphics window position
  97.  
  98.     graphic->Dispose();                                    //  Get rid of the graphic
  99.     
  100.     controls_directors->Dispose();                        //  Get rid of the controls list.  Note that the
  101.                                                         //   actual controls directors have already been
  102.                                                         //   disposed by CApplication's Quit method.
  103.  
  104.     inherited::Dispose();                //  Dispose of it as a Document
  105.  
  106. }    //==== CHyperCuberDoc::Dispose() ====\\
  107.  
  108.  
  109. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  110. //| CHyperCuberDoc::DoCommand
  111. //|
  112. //| Purpose: This handles document commands
  113. //|
  114. //| Paramters: command: the command to do
  115. //|__________________________________________
  116.  
  117. void CHyperCuberDoc::DoCommand(long command)
  118.  
  119. {
  120.  
  121.     CHyperCuberPane *main_pane =
  122.                     (CHyperCuberPane *) itsMainPane;
  123.  
  124.     if (command > cmdShowControlsWindowBase)                    //  Show or hide a controls window
  125.         {
  126.         
  127.         long dimension = command - cmdShowControlsWindowBase;    //  Find dimension controlled by window
  128.         
  129.         CControlsDirector *director =
  130.                     (CControlsDirector *) controls_directors->
  131.                                             NthItem(dimension);    //  Find the director of window    
  132.         
  133.         if (gPrefs->prefs.controls_window_visible[dimension])    //  Show or hide the window
  134.             director->HideWindow();
  135.         else
  136.             director->ShowWindow();
  137.  
  138.         gPrefs->prefs.controls_window_visible[dimension] = 
  139.             !gPrefs->prefs.controls_window_visible[dimension];    //  Reverse visibility of window in prefs
  140.  
  141.         return;                                                    //  Done with this command
  142.  
  143.         }
  144.  
  145.     switch (command) {
  146.  
  147.         case cmdMono:
  148.         
  149.             main_pane->StereoMode = mono;
  150.             main_pane->UpdateGraphicsPanes();            //  Adjust panes to new config., and redraw
  151.             break;
  152.         
  153.         case cmdTwoImageStereo:
  154.         
  155.             main_pane->StereoMode = two_image_stereo;
  156.             main_pane->graphic->SwitchToStereo();        //  Prepare graphic for switch
  157.             main_pane->UpdateGraphicsPanes();            //  Adjust panes to new config.
  158.             main_pane->Refresh();                        //  Redraw the object
  159.             break;
  160.         
  161.         case cmdTwoColorStereo:
  162.         
  163.             main_pane->StereoMode = two_color_stereo;
  164.             main_pane->graphic->SwitchToStereo();        //  Prepare graphic for switch
  165.             main_pane->UpdateGraphicsPanes();            //  Adjust panes to new config.
  166.             main_pane->Refresh();                        //  Redraw the object
  167.             break;
  168.         
  169.         case cmdAntialias:
  170.         
  171.             main_pane->fAntialias =
  172.                             !main_pane->fAntialias;        //  Toggle Antialiasing
  173.             main_pane->Refresh();                        //  Redraw the object
  174.             break;
  175.         
  176.         case cmdCopy:
  177.         
  178.             PicHandle object_pict;
  179.             CreatePICT(object_pict);
  180.             
  181.             gClipboard->EmptyGlobalScrap();                    //  Put the Picture in the clipboard
  182.             gClipboard->PutGlobalScrap('PICT',
  183.                             (Handle) object_pict);
  184.  
  185.             KillPicture(object_pict);                        //  Get rid of the picture
  186.  
  187.             break;
  188.  
  189.         case cmdToggleMenuBar:                                //  Toggle the menubar
  190.             
  191.             if (menubar_hidden)
  192.                 {
  193.                 show_menubar();                                //  Show the menubar
  194.                 
  195.                 gBartender->SetCmdText(cmdToggleMenuBar,    //  Change menu text to "Hide Menu Bar"
  196.                                         "\pHide Menu Bar");    //  Not that anyone will ever see this....
  197.                 }
  198.             else
  199.                 {
  200.                 hide_menubar();                                //  Hide the menubar
  201.  
  202.                 LongRect window_rect_long;                    //  Update the window which was under bar
  203.                 Rect window_rect;
  204.                 itsWindow->Prepare();
  205.                 itsWindow->GetFrame(&window_rect_long);
  206.                 LongToQDRect(&window_rect_long, &window_rect);
  207.                 window_rect.bottom = window_rect.top + menubar_height + 1;
  208.                 InvalRect(&window_rect);
  209.  
  210.                 gBartender->SetCmdText(cmdToggleMenuBar,    //  Change menu text to "Show Menu Bar"
  211.                                         "\pShow Menu Bar");
  212.                 
  213.                 }
  214.             break;
  215.             
  216.         case cmdToggleFullScreen:                            //  Make this window full-screen
  217.             
  218.             if (fFullScreen)
  219.                 {
  220.                 if (menubar_hidden)
  221.                     DoCommand(cmdToggleMenuBar);            //  There must be a menu bar if the window's
  222.                                                             //   not full screen.
  223.  
  224.                 ((CEnhancedWindow *) itsWindow)->
  225.                         Place(&normal_window_size);            //  Restore former window size
  226.                 fFullScreen = FALSE;                        //  It's no longer full screen
  227.  
  228.                 }
  229.  
  230.             else
  231.                 {
  232.                 ((CEnhancedWindow *) itsWindow)->
  233.                         GetRect(&normal_window_size);        //  Remember the current window position
  234.                 ((CEnhancedWindow *) itsWindow)->
  235.                         MakeFullScreen();                    //  Make the window full-screen
  236.                 fFullScreen = TRUE;                            //  It's now a full-screen window
  237.  
  238.                 }
  239.             break;
  240.  
  241.         default:    inherited::DoCommand(command);
  242.  
  243.             break;
  244.  
  245.     }
  246.     
  247. }    //==== CHyperCuberDoc::DoCommand() ====\\
  248.  
  249.  
  250.  
  251. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  252. //| CHyperCuberDoc::UpdateMenus
  253. //|
  254. //| Purpose: This method is called when the user clicks in the menu
  255. //|          bar.  It enables all menu items which should be enabled
  256. //|          when a HyperCuberDoc exists.
  257. //|
  258. //| Parameters: none
  259. //|___________________________________________________________________
  260.  
  261. void CHyperCuberDoc::UpdateMenus(void)
  262. {
  263.  
  264.     inherited::UpdateMenus();
  265.  
  266.     gBartender->EnableCmd(cmdCopy);                        //  Enable the Copy menu item  
  267.     gBartender->EnableCmd(cmdStereoMode);                //  Enable the Stereo mode submenu 
  268.     gBartender->EnableCmd(cmdAntialias);                //  Enable the Antialias menu item 
  269.     gBartender->EnableCmd(cmdToggleFullScreen);            //  Enable the Full Screen menu item 
  270.  
  271.     if (fFullScreen)
  272.         gBartender->EnableCmd(cmdToggleMenuBar);        //  Enable Toggle Menu Bar... if full screen
  273.  
  274.     CHyperCuberPane *main_pane =
  275.                 (CHyperCuberPane *) itsMainPane;
  276.  
  277.     gPrefs->Lock(TRUE);                                    //  Lock down the prefs
  278.     PrefsStruct *prefs = &(gPrefs->prefs);                //  Dereference prefs
  279.  
  280.     long i;
  281.     for (i = 3; i <= graphic->dimension; i++)            //  Check items in Windows menu    
  282.         {
  283.         gBartender->EnableCmd(
  284.                         cmdShowControlsWindowBase + i);    //  Enable the controls window command
  285.         gBartender->CheckMarkCmd(
  286.                     cmdShowControlsWindowBase + i,
  287.                     prefs->controls_window_visible[i]);    //  Check it if the controls window is visible
  288.         }
  289.                         
  290.     gBartender->EnableCmd(cmdMono);                        //  Enable the Stereo Mode submenu if Stereo is on
  291.     gBartender->EnableCmd(cmdTwoColorStereo);            //  Enable the Two-Color Stereo menu item 
  292.     gBartender->EnableCmd(cmdTwoImageStereo);            //  Enable the Two-Image Stereo menu item 
  293.  
  294.     gBartender->CheckMarkCmd(cmdMono,                    //  Check or uncheck Mono
  295.                 (main_pane->StereoMode == mono));
  296.     gBartender->CheckMarkCmd(cmdTwoImageStereo,            //  Check or uncheck Two-Image Stereo
  297.         (main_pane->StereoMode == two_image_stereo));
  298.     gBartender->CheckMarkCmd(cmdTwoColorStereo,            //  Check or uncheck Two-Color Stereo
  299.         (main_pane->StereoMode == two_color_stereo));
  300.     gBartender->CheckMarkCmd(cmdAntialias,                //  Check or uncheck Antialiasing
  301.                         main_pane->fAntialias);
  302.     gBartender->CheckMarkCmd(cmdToggleFullScreen,        //  Check or uncheck Full-Screen
  303.                         fFullScreen);
  304.  
  305.     gPrefs->Lock(FALSE);                        //  Unlock the prefs
  306.  
  307. }    //==== CHyperCuberDoc::UpdateMenus() ====\\
  308.  
  309.  
  310.  
  311.  
  312. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  313. //| CHyperCuberDoc::Activate
  314. //|
  315. //| Purpose: Activate this director, and show its controls windows
  316. //|
  317. //| Parameters: none
  318. //|__________________________________________________________________
  319.  
  320. void CHyperCuberDoc::Activate(void)
  321. {   
  322.  
  323.     CDocument::Activate();                                    //  Call superclass
  324.     
  325. #define WINDOWS_MENU_ID    130
  326. #define BASE_WINDOWS_MENU_ITEMS    3
  327.  
  328.     long i;
  329.     for (i = 3; i <= graphic->dimension; i++)                //  Add menu items to show/hide control windows
  330.         {
  331.         char menu_item_text[30];
  332.         sprintf(menu_item_text, "%dD Controls", i);
  333.         gBartender->InsertMenuCmd(cmdShowControlsWindowBase + i,
  334.                         CtoPstr(menu_item_text),
  335.                         WINDOWS_MENU_ID,
  336.                         BASE_WINDOWS_MENU_ITEMS + i - 3);    //  Add "nD Controls" to the end of the menu
  337.         }
  338.         
  339.     if (!itsWindow) return;                                    //  Don't do anything with windows if we're just
  340.                                                             //    creating this document
  341.     
  342.     for (i = 3; i <= graphic->dimension; i++)
  343.         {
  344.         CControlsDirector *director = (CControlsDirector *) controls_directors->NthItem(i);
  345.  
  346.         if (gPrefs->prefs.controls_window_visible[i])
  347.             director->GetWindow()->ShowFloat();                //  Show the window if it should be visible
  348.     
  349.         }
  350.  
  351.     BecomeGopher(TRUE);
  352.  
  353. }    //==== CHyperCuberDoc::Activate() ====\\
  354.  
  355.  
  356.  
  357. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  358. //| CHyperCuberDoc::Deactivate
  359. //|
  360. //| Purpose: Deactivate this director, and hide its controls windows
  361. //|
  362. //| Parameters: none
  363. //|__________________________________________________________________
  364.  
  365. void CHyperCuberDoc::Deactivate(void)
  366. {   
  367.  
  368.     CDocument::Deactivate();                            //  Call superclass
  369.  
  370.     long i;
  371.     for (i = 3; i <= graphic->dimension; i++)            //  Remove menu items to show/hide control windows
  372.         gBartender->RemoveMenuCmd(cmdShowControlsWindowBase + i);
  373.  
  374.     if (!itsWindow)
  375.         return;                                            //  Don't try to dispose of controls 
  376.                                                         //    windows if we're closing document
  377.  
  378.     for (i = 3; i <= graphic->dimension; i++)
  379.         {
  380.         CControlsDirector *director =
  381.                     (CControlsDirector *)
  382.                         controls_directors->NthItem(i);
  383.  
  384.         if (gPrefs->prefs.controls_window_visible[i])
  385.             director->GetWindow()->HideFloat();            //  Hide the window if it is visible
  386.         }
  387.  
  388. }    //==== CHyperCuberDoc::Deactivate() ====\\
  389.  
  390.  
  391.  
  392. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  393. //| CHyperCuberDoc::Suspend
  394. //|
  395. //| Purpose: Suspend this director (switching to another process)
  396. //|
  397. //| Parameters: none
  398. //|__________________________________________________________________
  399.  
  400. void CHyperCuberDoc::Suspend(void)
  401. {   
  402.  
  403.     inherited::Suspend();
  404.     
  405.     itsWindow->Deactivate();
  406.     
  407. }    //==== CHyperCuberDoc::Suspend() ====\\
  408.  
  409.  
  410.  
  411. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  412. //| CHyperCuberDoc::Resume
  413. //|
  414. //| Purpose: Resume this director (switching from another process)
  415. //|
  416. //| Parameters: none
  417. //|__________________________________________________________________
  418.  
  419. void CHyperCuberDoc::Resume(void)
  420. {   
  421.  
  422.     inherited::Resume();
  423.     
  424.     itsWindow->Activate();
  425.     
  426. }    //==== CHyperCuberDoc::Resume() ====\\
  427.  
  428.  
  429.  
  430. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  431. //| CHyperCuberDoc::DoKeyDown
  432. //|
  433. //| Purpose: This is called when the user presses a key
  434. //|
  435. //| Parameters: theChar: char code of the key pressed
  436. //|             keyCode: key code of the key pressed
  437. //|             macEvent: keydown event
  438. //|______________________________________________________________
  439.  
  440. void CHyperCuberDoc::DoKeyDown(char theChar, Byte keyCode, EventRecord *macEvent)
  441. {
  442.  
  443.     gPrefs->Lock(TRUE);
  444.  
  445.     short modifiers = (macEvent->modifiers &
  446.         (cmdKey | optionKey | shiftKey | controlKey | alphaLock));//  Get the modifiers
  447.     key_control_struct *key_controls =
  448.                     gPrefs->prefs.key_controls;                    //  Get the key controls array
  449.     
  450.     long i;
  451.     for (i = 0; i <= gPrefs->prefs.num_key_controls; i++)        //  Loop through all key controls
  452.         {
  453.         if ((key_controls[i].key_code == keyCode) &&
  454.             (key_controls[i].modifiers == modifiers))            //  Check if we should use this
  455.             {
  456.             key_control_struct key_control = key_controls[i];    //  Get the key control record
  457.             
  458.             CControlsDirector *controls_director =
  459.                     (CControlsDirector *)
  460.                         controls_directors->
  461.                             NthItem(key_control.dimension);        //  Find the controls
  462.             
  463.             controls_director->OffsetScrollBar(
  464.                     key_control.angle, key_control.increment);    // Update the scroll bar
  465.             }
  466.         }
  467.     
  468.     gPrefs->Lock(FALSE);
  469.  
  470. }    //==== CHyperCuberDoc::DoKeyDown() ====\\
  471.  
  472.  
  473.  
  474. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  475. //| CHyperCuberDoc::DoAutoKey
  476. //|
  477. //| Purpose: This is called when the a key repeats
  478. //|
  479. //| Parameters: theChar: char code of the key pressed
  480. //|             keyCode: key code of the key pressed
  481. //|             macEvent: keydown event
  482. //|______________________________________________________________
  483.  
  484. void CHyperCuberDoc::DoAutoKey(char theChar, Byte keyCode, EventRecord *macEvent)
  485. {
  486.  
  487.     DoKeyDown(theChar, keyCode, macEvent);        //  Same as DoKeyDown
  488.  
  489. }    //==== CHyperCuberDoc::DoAutoKey() ====\\
  490.  
  491.  
  492.  
  493. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  494. //| CHyperCuberDoc::NewFile
  495. //|
  496. //| Purpose: Create a new window for the new document
  497. //|
  498. //| Parameters: none
  499. //|_________________________________________________________
  500.  
  501. void CHyperCuberDoc::NewFile(void)
  502. {   
  503.  
  504. #define THREE_COLOR_HYPERCUBE_ID    128
  505.  
  506.     NewFileFromTEXT(THREE_COLOR_HYPERCUBE_ID);        //  Display a three-color hypercube
  507.  
  508. }    //==== CHyperCuberDoc::NewFile() ====\\
  509.  
  510.  
  511. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  512. //| CHyperCuberDoc::NewNCube
  513. //|
  514. //| Purpose: Create a new n-dimensional cube
  515. //|
  516. //| Parameters: dimension: dimension of the n-cube
  517. //|_________________________________________________________
  518.  
  519. void CHyperCuberDoc::NewNCube(long dimension)
  520. {
  521.  
  522.     char filename[10];
  523.  
  524.     if (dimension == 3)
  525.         strcpy(filename, "Cube");                //  Set the filename to describe to the object
  526.         
  527.     else if (dimension == 4)
  528.         strcpy(filename, "Hypercube");
  529.     
  530.     else
  531.         sprintf(filename, "%d-Cube", dimension);
  532.  
  533.     CreateNCube(dimension, filename);            //  Create an n-cube file
  534.     OpenFileFromFilename(filename);                //  Open the file
  535.     short err = remove(filename);                //  Delete the file
  536.  
  537. }    //==== CHyperCuberDoc::NewNCube() ====\\
  538.  
  539.  
  540.  
  541. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  542. //| CHyperCuberDoc::OpenFile
  543. //|
  544. //| Purpose: Open the file the user selected, and create a new window for it
  545. //|
  546. //| Parameters: macSFReply: the file information
  547. //|__________________________________________________________________________
  548.  
  549. void CHyperCuberDoc::OpenFile(SFReply *macSFReply)
  550.  
  551. {
  552.     
  553.     short working_dir_id = macSFReply->vRefNum;        //  Set the default directory to the input file's
  554.     SetVol ((StringPtr) NULL, working_dir_id);        //    directory
  555.  
  556.     char    filename[32];                            //  Get the filename
  557.     strcpy (filename, PtoCstr(macSFReply->fName));
  558.     
  559.     OpenFileFromFilename(filename);                    //  Open file
  560.  
  561. }    //==== OpenFile() ====\\
  562.  
  563.  
  564.  
  565. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  566. //| CHyperCuberDoc::OpenFileFromFilename
  567. //|
  568. //| Purpose: Open the file, given the filename
  569. //|
  570. //| Parameters: filename: the filename
  571. //|__________________________________________________________________________
  572.  
  573. void CHyperCuberDoc::OpenFileFromFilename(char *filename)
  574. {
  575.     
  576.     ifstream fs;
  577.     fs.open(filename);                                    //  Open the file
  578.     long g;
  579.     fs >> *graphic;                                        //  Read the graphic
  580.     fs.close();                                            //  Close the file
  581.  
  582.     BuildGraphicsWindow();                                //  Build a graphics window for this file
  583.     itsWindow->SetTitle(CtoPstr(filename));                //  Set the window name to the filename
  584.     PtoCstr((unsigned char *) filename);
  585.  
  586.     controls_directors->Append((CObject *) NULL);        // Add null items for dimensions 1 and 2
  587.     controls_directors->Append((CObject *) NULL);
  588.     
  589.     long i;
  590.     for (i = 3; i <= graphic->dimension; i++)
  591.         {
  592.         CControlsDirector *controls_director;
  593.         controls_director = new(CControlsDirector);        //  Create a controls director for this
  594.         controls_director->IControlsDirector(this,
  595.                 (CHyperCuberPane *) itsMainPane, i);    //    dimension
  596.  
  597.         controls_directors->Append(controls_director);    //  Add this director to the list
  598.         }
  599.  
  600.     itsWindow->Select();                                //  Make the window active
  601.  
  602.     graphic->Project(graphic->dimension);                //  Do all projections for graphic
  603.  
  604.     Rect no_change = {0, 0, 0, 0};
  605.     CHyperCuberPane *main_pane =
  606.                 (CHyperCuberPane *) itsMainPane;
  607.     main_pane->AdjustToEnclosure(&no_change);            //  Recalc graphics panes (and draw object)
  608.  
  609. }    //==== OpenFileFromFilename() ====\\
  610.  
  611.  
  612.  
  613. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  614. //| CHyperCuberDoc::NewFileFromTEXT
  615. //|
  616. //| Purpose: Get a new document, with graphic defined from a TEXT resource
  617. //|
  618. //| Parameters: TEXT_id: the resource id of the TEXT resouce
  619. //|__________________________________________________________________________
  620.  
  621. void CHyperCuberDoc::NewFileFromTEXT(short TEXT_id)
  622. {
  623.     
  624.     Handle TEXT_handle = GetResource('TEXT', TEXT_id);    //  Get the TEXT resource
  625.     short string_length = GetHandleSize(TEXT_handle);    //  Get the length
  626.     SetHandleSize(TEXT_handle, string_length+1);        //  Add an extra byte for null terminator
  627.     HLock(TEXT_handle);
  628.     
  629.     char *text_string = *TEXT_handle;                    //  Get a C string
  630.     text_string[string_length] = '\0';                    //  Add a terminator
  631.     
  632.     strstream s;
  633.     s << text_string;                                    //  Write the text string to the stream
  634.     s >> *graphic;                                        //  Read the graphic from the stream
  635.  
  636.     DisposHandle(TEXT_handle);                            //  Dispose of the TEXT resource in memory    
  637.  
  638.     BuildGraphicsWindow();                                //  Build a graphics window for this file
  639.     itsWindow->SetTitle("\pHyperCube");                    //  Set the window name
  640.  
  641.     controls_directors->Append((CObject *) NULL);        // Add null items for dimensions 1 and 2
  642.     controls_directors->Append((CObject *) NULL);
  643.     
  644.     long i;
  645.     for (i = 3; i <= graphic->dimension; i++)
  646.         {
  647.         CControlsDirector *controls_director;
  648.         controls_director = new(CControlsDirector);        //  Create a controls director for this
  649.         controls_director->IControlsDirector(this,
  650.                 (CHyperCuberPane *) itsMainPane, i);    //    dimension
  651.  
  652.         controls_directors->Append(controls_director);    //  Add this director to the list
  653.         }
  654.  
  655.     itsWindow->Select();                                //  Make the window active
  656.  
  657.     graphic->Project(graphic->dimension);                //  Do all projections for graphic
  658.  
  659.     Rect no_change = {0, 0, 0, 0};
  660.     CHyperCuberPane *main_pane =
  661.                 (CHyperCuberPane *) itsMainPane;
  662.     main_pane->AdjustToEnclosure(&no_change);            //  Recalc graphics panes (and draw object)
  663.  
  664. }    //==== CHyperCuberDoc::NewFileFromTEXT() ====\\
  665.  
  666.  
  667.  
  668. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  669. //| CHyperCuberDoc::BuildGraphicsWindow
  670. //|
  671. //| Purpose: Builds the graphics window
  672. //|
  673. //| Parameters: none
  674. //|_________________________________________________________
  675.  
  676. void CHyperCuberDoc::BuildGraphicsWindow (void)
  677.  
  678. {
  679.  
  680. #define    TWO_IMAGE        128
  681. #define    TWO_COLOR        129
  682.  
  683.     itsWindow = new(CEnhancedWindow);                    //  Create the window
  684.     ((CEnhancedWindow *) itsWindow)->
  685.                 IEnhancedWindow(WINDHyperCuber, FALSE,
  686.                     gDesktop, this);
  687.     itsWindow->helpResID = WINDOW_HELP_RES;
  688.  
  689.     Rect size_rect;                                        //  Limit size of window to size of
  690.     gDesktop->GetBounds(&size_rect);                    //  desktop and make sure it's always
  691.     size_rect.left = 50;                                //  large enough to be visible.
  692.     size_rect.top = 50;
  693.     itsWindow->SetSizeRect(&size_rect);
  694.  
  695.     ((CEnhancedWindow *) itsWindow)->
  696.         PlaceWithVerify(
  697.             &gPrefs->prefs.graphics_window_position);    //  Place the window in the default position
  698.                                                         //  (but not offscreen)
  699.         
  700.     CHyperCuberPane    *theMainPane;
  701.     theMainPane = new(CHyperCuberPane);                    //  Setup the main pane
  702.     theMainPane->IHyperCuberPane(itsWindow, this,
  703.                                 100, 100, 10, 10,
  704.                                 sizELASTIC, sizELASTIC);
  705.     itsMainPane = theMainPane;                            //  Make this the main pane
  706.     itsGopher = theMainPane;                            //  Make it the gopher
  707.     theMainPane->FitToEnclosure(TRUE, TRUE);            //  Expand it to fill the window
  708.     theMainPane->SetWantsClicks(TRUE);                    //  Let the controls get clicks
  709.     theMainPane->helpResIndex = kImage;                    //  Link to Balloon Help
  710.  
  711.     short window_width, window_height;
  712.     theMainPane->GetLengths(&window_width,                //  Get width and height of window
  713.                                 &window_height);
  714.  
  715.     CSizeBox *size_box = new(CSizeBox);                    //  Add a size box in lower right
  716.     size_box->ISizeBox(itsWindow, this);
  717.  
  718.     short pane_width, pane_height;
  719.     theMainPane->GetLengths(&pane_width, &pane_height);
  720.     
  721.     theMainPane->graphic = graphic;                        //  Link the main pane to its graphic
  722.     graphic->pane = theMainPane;                        //  Link the graphic to the main pane
  723.  
  724.     Rect pane_bounds = {0, 0, pane_height, pane_width};
  725.     adjust_offscreen_pixmap(&theMainPane->OffscreenPort,//  Make offscreen bitmap large enough
  726.                                     &pane_bounds);
  727.     
  728. }    //==== CHyperCuberDoc::BuildGraphicsWindow() ====\\
  729.  
  730.  
  731.  
  732. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  733. //| CHyperCuberDoc::DoSaveAs
  734. //|
  735. //| Purpose: Save the graphic as a PICT file
  736. //|
  737. //| Parameters: macSFReply: the file to save to
  738. //|_________________________________________________________
  739.  
  740. Boolean    CHyperCuberDoc::DoSaveAs(SFReply *macSFReply)
  741. {
  742.  
  743. #if 0
  744.     static frame = 0;
  745.     sprintf((char *) macSFReply->fName, "f%d", frame++);    //  Save picture to frame file.  This
  746.     CtoPstr((char *) macSFReply->fName);                    //   code can be used to create movies.
  747. #endif
  748.  
  749.  
  750.     FSSpec spec;
  751.     short error;
  752.     error = FSMakeFSSpec(macSFReply->vRefNum, 0,         //  Create FSSpec for PICT file
  753.                         macSFReply->fName, &spec);
  754.  
  755.     PicHandle object_pict;
  756.     CreatePICT(object_pict);
  757.  
  758.     short file_refnum;
  759.     error = FSpDelete(&spec);                            //  Create PICT file
  760.     error = FSpCreate(&spec, 'ttxt', 'PICT',
  761.                         iuSystemScript);
  762.     error = FSpOpenDF(&spec, fsWrPerm, &file_refnum);
  763.     
  764.     long header_size = 512;                                //  Write empty PICT file header
  765.     Handle header_handle = NewHandleClear(header_size);
  766.     HLock(header_handle);
  767.     error = FSWrite(file_refnum, &header_size,
  768.                         *header_handle);
  769.     DisposHandle(header_handle);
  770.     
  771.     long pict_size = GetHandleSize(                        //  Write the PICT
  772.                         (Handle) object_pict);    
  773.     HLock((Handle) object_pict);
  774.     error = FSWrite(file_refnum, &pict_size,
  775.                         *object_pict);
  776.     
  777.     error = FSClose(file_refnum);                        //  Close the PICT file
  778.  
  779.     KillPicture(object_pict);                            //  Get rid of the picture
  780.  
  781.     return TRUE;
  782.  
  783. }    //==== CHyperCuberDoc::DoSaveAs() ====\\
  784.  
  785.  
  786.  
  787. //|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  788. //| CHyperCuberDoc::CreatePICT
  789. //|
  790. //| Purpose: Create a PICT from the graphic
  791. //|
  792. //| Parameters: hypercube_pict: receives the PICT
  793. //|_________________________________________________________
  794.  
  795. void CHyperCuberDoc::CreatePICT(PicHandle& hypercube_pict)
  796. {
  797.  
  798.     LongRect frame_rect_long;                
  799.     OpenCPicParams pict_params;
  800.     CHyperCuberPane *main_pane =
  801.                 (CHyperCuberPane *) itsMainPane;
  802.     main_pane->GetFrame(&frame_rect_long);            //  Get the frame in frame coordinates
  803.                             
  804.     main_pane->FrameToWindR(&frame_rect_long,        //  Convert frame to window coordinates
  805.                         &(pict_params.srcRect));
  806.     pict_params.hRes =                                //  72dps resolution
  807.                 pict_params.vRes = 0x00480000;
  808.     pict_params.version = -2;                        //  Version 2 picture
  809.     
  810.     main_pane->Prepare();                            //  Prepare to draw to graphics frame
  811.     hypercube_pict = OpenCPicture(&pict_params);    //  Start recording a Picture
  812.                             
  813.     
  814.     if (!main_pane->fAntialias)
  815.         main_pane->fDrawOffscreen = FALSE;            //  If we're not antialiasing, create
  816.                                                     //    an object-type picture.  Else
  817.                                                     //    create a bitmap.
  818.     
  819.     main_pane->Draw((Rect *) NULL);                    //  Redraw the object
  820.  
  821.     main_pane->fDrawOffscreen = TRUE;
  822.  
  823.     ClosePicture();                                    //  Stop recording the Picture
  824.     
  825.     RGBColor rgb_white = {0xFFFF, 0xFFFF, 0xFFFF};    //  Restore colors
  826.     RGBColor rgb_black = {0x0000, 0x0000, 0x0000};
  827.     RGBForeColor(&rgb_black);
  828.     RGBBackColor(&rgb_white);
  829.             
  830. }    //==== CHyperCuberDoc::CreatePICT() ====\\
  831.